/*
 * Copyright (c) 2023-2025 elsfs Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.elsfs.cloud.common.mybatis.ext.sql;

import java.util.function.Consumer;
import org.elsfs.cloud.common.core.entity.BaseEntity;
import org.elsfs.cloud.common.mybatis.ext.sql.support.builder.StandardSelectSql;

/**
 * JOIN连接SQL
 *
 * @param <C> 子类具体类型
 * @param <JB> JOIN构建器类型
 * @param <JCB> JOIN条件构建器类型
 */
public interface Join<
        C extends Join<C, JB, JCB>,
        JB extends JoinBuilder<JB, JCB, C>,
        JCB extends JoinConditionBuilder<JCB, JB, C>>
    extends SqlFragment {

  /** 主表别名 */
  String TABLE_ALIAS = "t";

  /**
   * 内连接一张表
   *
   * @param entityClass 实体类
   * @return 连接配置对象
   */
  JB join(Class<? extends BaseEntity> entityClass);

  /**
   * 内连接一张表
   *
   * @param entityClass 实体类
   * @param tableAlias 表别名
   * @return 连接配置对象
   */
  JB join(Class<? extends BaseEntity> entityClass, String tableAlias);

  /**
   * 内连接一张表
   *
   * @param entityClass 实体类
   * @param tableAlias 表别名
   * @param registerAlias 是否注册别名
   * @return 连接配置对象
   */
  JB join(Class<? extends BaseEntity> entityClass, String tableAlias, boolean registerAlias);

  /**
   * 内连接一张表
   *
   * @param table 数据库表名
   * @return 连接配置对象
   */
  JB join(String table);

  /**
   * 内连接一张表
   *
   * @param table 数据库表名
   * @param tableAlias 表别名
   * @return 连接配置对象
   */
  JB join(String table, String tableAlias);

  /**
   * 内连接一张表
   *
   * @param table 数据库表名
   * @param tableAlias 表别名
   * @param registerAlias 是否注册别名
   * @return 连接配置对象
   */
  JB join(String table, String tableAlias, boolean registerAlias);

  /**
   * 内连接一个子查询
   *
   * @param sqlBuilderConsumer 子查询构建器
   * @param tableAlias 表别名
   * @return 连接配置对象
   */
  JB join(Consumer<StandardSelectSql> sqlBuilderConsumer, String tableAlias);

  /**
   * 左连接一张表
   *
   * @param entityClass 实体类
   * @return 连接配置对象
   */
  JB leftJoin(Class<? extends BaseEntity> entityClass);

  /**
   * 左连接一张表
   *
   * @param entityClass 实体类
   * @param tableAlias 表别名
   * @return 连接配置对象
   */
  JB leftJoin(Class<? extends BaseEntity> entityClass, String tableAlias);

  /**
   * 左连接一张表
   *
   * @param entityClass 实体类
   * @param tableAlias 表别名
   * @param registerAlias 是否注册别名
   * @return 连接配置对象
   */
  JB leftJoin(Class<? extends BaseEntity> entityClass, String tableAlias, boolean registerAlias);

  /**
   * 左连接一张表
   *
   * @param table 数据库表名
   * @return 连接配置对象
   */
  JB leftJoin(String table);

  /**
   * 左连接一张表
   *
   * @param table 数据库表名
   * @param tableAlias 表别名
   * @return 连接配置对象
   */
  JB leftJoin(String table, String tableAlias);

  /**
   * 左连接一张表
   *
   * @param table 数据库表名
   * @param tableAlias 表别名
   * @param registerAlias 是否注册别名
   * @return 连接配置对象
   */
  JB leftJoin(String table, String tableAlias, boolean registerAlias);

  /**
   * 左连接一个子查询
   *
   * @param sqlBuilderConsumer 子查询构建器
   * @param tableAlias 表别名
   * @return 连接配置对象
   */
  JB leftJoin(Consumer<StandardSelectSql> sqlBuilderConsumer, String tableAlias);

  /**
   * 右连接一张表
   *
   * @param entityClass 实体类
   * @return 连接配置对象
   */
  JB rightJoin(Class<? extends BaseEntity> entityClass);

  /**
   * 右连接一张表
   *
   * @param entityClass 实体类
   * @param tableAlias 表别名
   * @return 连接配置对象
   */
  JB rightJoin(Class<? extends BaseEntity> entityClass, String tableAlias);

  /**
   * 右连接一张表
   *
   * @param entityClass 实体类
   * @param tableAlias 表别名
   * @param registerAlias 是否注册别名
   * @return 连接配置对象
   */
  JB rightJoin(Class<? extends BaseEntity> entityClass, String tableAlias, boolean registerAlias);

  /**
   * 右连接一张表
   *
   * @param table 数据库表名
   * @return 连接配置对象
   */
  JB rightJoin(String table);

  /**
   * 右连接一张表
   *
   * @param table 数据库表名
   * @param tableAlias 表别名
   * @return 连接配置对象
   */
  JB rightJoin(String table, String tableAlias);

  /**
   * 右连接一张表
   *
   * @param table 数据库表名
   * @param tableAlias 表别名
   * @param registerAlias 是否注册别名
   * @return 连接配置对象
   */
  JB rightJoin(String table, String tableAlias, boolean registerAlias);

  /**
   * 右连接一个子查询
   *
   * @param sqlBuilderConsumer 子查询构建器
   * @param tableAlias 表别名
   * @return 连接配置对象
   */
  JB rightJoin(Consumer<StandardSelectSql> sqlBuilderConsumer, String tableAlias);
}
